package com.zkyc.framework.website.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.zkyc.framework.common.constant.NumberConstant;
import com.zkyc.framework.common.mapper.ColumnDataClickRateMapper;
import com.zkyc.framework.common.mapper.SystemLogMapper;
import com.zkyc.framework.common.mapper.WebClickRateMapper;
import com.zkyc.framework.common.pojo.Column;
import com.zkyc.framework.common.pojo.ColumnData;
import com.zkyc.framework.common.pojo.SystemLog;
import com.zkyc.framework.common.pojo.User;
import com.zkyc.framework.common.vo.ResultVO;
import com.zkyc.framework.common.vo.user.UserDashBoardVo;
import com.zkyc.framework.website.client.UserClient;
import com.zkyc.framework.website.mapper.*;
import com.zkyc.framework.website.service.DashBoardService;
import com.zkyc.framework.website.util.TokenUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DashBoardServiceImpl implements DashBoardService {
    @Autowired
    private WebClickRateMapper webClickRateMapper;
    @Autowired
    private ContentMapper contentMapper;
    @Autowired
    private ClickRateMapper clickRateMapper;
    @Autowired
    private SystemLogMapper systemLogMapper;
    @Autowired
    private UserClient userClient;
    @Autowired
    private ColumnDataClickRateMapper dataClickRateMapper;
    @Autowired
    private MoudleMapper moudleMapper;
    @Autowired
    private ColumnMapper columnMapper;
    @Autowired
    private ColumnDataMapper dataMapper;

    @Override
    public ResultVO getDashboardData(Integer websiteId) {
        String userId = TokenUserUtil.getCurrentUserId();
        UserDashBoardVo userDashBoardVo = new UserDashBoardVo();
        JSONObject judgeRightExistJson = new JSONObject();
        if (userId != null) {
            QueryWrapper<SystemLog> queryWrapper = new QueryWrapper<>();
            ResultVO<?> userById = userClient.getUserById(userId);
            ResultVO judgeRightExist = userClient.judgeRightExist(websiteId, userId);
            judgeRightExistJson = JSONObject.parseObject(JSONObject.toJSONString(judgeRightExist.getData()));
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(userById));
            User user = JSONObject.parseObject(jsonObject.getString("data"), User.class);
            if (user.getUsername() != null){
                queryWrapper.eq("operator_username", user.getUsername());
            }
            queryWrapper.orderByDesc("operate_date");
            queryWrapper.last("limit 1,1");
            SystemLog systemLog = systemLogMapper.selectOne(queryWrapper);
            if (systemLog != null){
                BeanUtils.copyProperties(systemLog,userDashBoardVo);
            }
        }
        JSONObject jsonObject = new JSONObject();
        int avgClickRate = getRate(webClickRateMapper.getAvgClickRate(websiteId));
        int todayClickRate = getRate(webClickRateMapper.getTodayClickRate(websiteId));
        List<JSONObject> sevenDaysClickRate = webClickRateMapper.getSevenDaysClickRate(websiteId);
        List<JSONObject> avgCostTime = webClickRateMapper.getAvgCostTime(websiteId);

        Integer publishCount;
        List<JSONObject> top5;
        if (websiteId == 1) {
            top5 = clickRateMapper.getTop5(websiteId);
            publishCount = contentMapper.getPublishCount(websiteId);
        } else {
            top5 = getTop5(websiteId);
            publishCount = getPublishCount(websiteId);
        }

        jsonObject.put("publishCount", publishCount);
        jsonObject.put("avgClickRate", avgClickRate);
        jsonObject.put("todayClickRate", todayClickRate);
        jsonObject.put("sevenDaysClickRate", sevenDaysClickRate);
        jsonObject.put("avgCostTime", avgCostTime);
        jsonObject.put("top5", top5);
        jsonObject.put("userInformation", userDashBoardVo);
        jsonObject.put("userRight",judgeRightExistJson);
        return ResultVO.data(jsonObject);
    }

    private Integer getPublishCount(Integer websiteId) {
        List<Integer> columnIdList = getColumnIdList(websiteId);
        if (CollectionUtils.isEmpty(columnIdList)) {
            return NumberConstant.NUMBER_0;
        }
        LambdaQueryWrapper<ColumnData> columnDataLqw = new LambdaQueryWrapper<>();
        columnDataLqw.in(ColumnData::getColumnId, columnIdList).eq(ColumnData::getStatus, NumberConstant.NUMBER_1);
        return dataMapper.selectCount(columnDataLqw);
    }

    private List<JSONObject> getTop5(Integer websiteId) {
        List<Integer> columnIdList = getColumnIdList(websiteId);
        // 拼接条件
        if (CollectionUtils.isEmpty(columnIdList)) {
            return Collections.emptyList();
        }
        return dataClickRateMapper.getTop5(columnIdList);
    }

    private List<Integer> getColumnIdList(Integer websiteId) {
        List<Integer> columnTypeList = new ArrayList<>(NumberConstant.NUMBER_2);
        columnTypeList.add(NumberConstant.NUMBER_2);
        columnTypeList.add(NumberConstant.NUMBER_4);
        // 只需要查各个网站columnType为2的栏目
        // 首先查该网站有哪些模块
        List<Integer> moudleIdList = moudleMapper.queryMoudleByWebsiteIdPlus(websiteId);
        // 再查这些模块下有哪些columnType为2的栏目的id
        if (CollectionUtils.isEmpty(moudleIdList)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Column> columnLqw = new LambdaQueryWrapper<>();
        // 只需要查id
        columnLqw.select(Column::getId);
        columnLqw.in(Column::getMoudleId, moudleIdList);
        columnLqw.in(Column::getColumnType, columnTypeList);
        List<Column> columnList = columnMapper.selectList(columnLqw);
        return columnList.stream().map(Column::getId).collect(Collectors.toList());
    }

    private int getRate(String rateString) {
        if (rateString == null) {
            rateString = StringPool.ZERO;
        }
        return (int) Double.parseDouble(rateString);
    }
}
